package cn.kgc;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author YC
 * 如果节点存在，获得节点的数据，同时监听当前节点下的子节点的列表，一旦有当前节点下有新节点或从当前节点下删除节点
 */
public class GetNodeData implements Watcher {

    /**
     * 倒计时闩锁，初始值为1
     */
    private static final CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(1);

    public static void main(String[] args) {
        try (ZooKeeper zooKeeper = new ZooKeeper("192.168.8.106:2181", 5000, new GetNodeData())) {
            // 等待连接（倒计时闩锁值为0才能连接）
            COUNT_DOWN_LATCH.await();
            // 连接状态为：CONNECTED
            System.out.println(zooKeeper.getState());
            // 判断节点是否存在
            Stat stat = zooKeeper.exists("/kgc-test", null);
            if (stat != null) {
                // 获得节点数据 并监听此节点
                byte[] data = zooKeeper.getData("/kgc-test", new Watcher() {
                    @Override
                    public void process(WatchedEvent watchedEvent) {
                        if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
                            try {
                                // 监听到子节点列表变化，重新获取子节点列表
                                List<String> children = zooKeeper.getChildren("/kgc-test", this);
                                System.out.println("节点下的最新子节点集合：" + children);
                            } catch (KeeperException | InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }, stat);
                System.out.println("节点数据：" + new String(data));
            } else {
                System.out.println("节点不存在");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 事件通知
     *
     * @param watchedEvent 事件
     */
    @Override
    public void process(WatchedEvent watchedEvent) {
        // 客户端监听服务端的连接事件
        if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
            // 连接成功则释放倒计时闩锁（值-1）
            COUNT_DOWN_LATCH.countDown();
        }
    }

}
